package com.wsx.ones.sharding;

import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;
import com.google.common.collect.Range;
import com.wsx.ones.finalstr.common.ShardingUtil;

import java.util.Collection;
import java.util.LinkedHashSet;

/**
 * 支付体系中账户信息的分库设置
 * 该算法实现的是区间分布的实现，根据支付账户信息进行区间的分库设置
 * 0 ~ 3000000 db1    3000000 ~ 6000000 db2  ……的算法实现，可以动态的扩展数据库
 * 支付账户信息采用的是分库不分表的设计
 * Created by wangshuaixin on 17/1/6.
 */
public class PayKeyDatabaseSharding implements SingleKeyDatabaseShardingAlgorithm<Integer> {

    @Override
    public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {

        for (String database : availableTargetNames) {
            //根据数据计算的所属那个数据库
            int db_num = shardingValue.getValue() / ShardingUtil.COUNT_PER_DB;
            if (database.endsWith(String.valueOf(db_num))) {
                return database;
            }
        }
        throw new IllegalArgumentException();
    }

    @Override
    public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {
        Collection<String> databases = new LinkedHashSet<String>(availableTargetNames.size());
        for (Integer value : shardingValue.getValues()) {
            int db_num = value / ShardingUtil.COUNT_PER_DB;
            for (String database : availableTargetNames) {
                if (database.endsWith(String.valueOf(db_num))) {
                    databases.add(database);
                }
            }
        }
        return databases;
    }

    @Override
    public Collection<String> doBetweenSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {
        Collection<String> databases = new LinkedHashSet<String>(availableTargetNames.size());
        Range<Integer> range = shardingValue.getValueRange();
        for (int start = range.lowerEndpoint(); start <= range.upperEndpoint(); start++) {
            int db_num = start / ShardingUtil.COUNT_PER_DB;
            for (String database : availableTargetNames) {
                if (database.endsWith(String.valueOf(db_num))) {
                    databases.add(database);
                }
            }
        }
        return databases;
    }
}
